/*
 * Copyright 2021 yhuan416
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "sbull.h"
#include "sbull_internal.h"

// MTD
static struct MtdDev g_sbull_mtd_dev = {
    .priv = NULL,
    .type = MTD_NORFLASH,
    .size = 0,
    .eraseSize = SBULL_ERASE_SIZE,
    .erase = sbull_mtd_erase,
    .read = sbull_mtd_read,
    .write = sbull_mtd_write,
};

// BLK
static struct block_operations g_sbull_blk_ops = { 
    .open       = sbull_blk_open,
    .close      = sbull_blk_close,
    .read       = sbull_blk_read,
    .write      = sbull_blk_write,
    .geometry   = sbull_blk_geometry
};

// Char
static struct file_operations_vfs g_sbull_char_ops = {
    .open   = sbull_char_open,
    .close  = sbull_char_close,
    .read   = sbull_char_read,
    .write  = sbull_char_write,
    .seek   = sbull_char_seek
};

void *GetMtd(const char *type)
{
    (void)type;// if type == "spinor"
    return &g_sbull_mtd_dev;
}

int FreeMtd(struct MtdDev *mtd)
{
    /* do nothing. */
    (void)mtd;
    return 0;
}

struct block_operations *GetDevSpinorOps(void)
{
    return &g_sbull_blk_ops;
}

struct block_operations *GetDevNandOps(void)
{
    return &g_sbull_blk_ops;
}

struct file_operations_vfs *GetMtdCharFops(void)
{
    return &g_sbull_char_ops;
}

int32_t sbull_init(struct Sbull *sbull, uint32_t vbase, uint32_t size)
{
    struct MtdDev *mtd = GetMtd("spinor");

    if (sbull == NULL || mtd == NULL) { 
        return -1; 
    };

    // 填充sbull属性
    sbull->base = (uint8_t *)vbase;
    sbull->size = size;

    // 填充mtd属性
    mtd->priv = (void *)sbull;
    mtd->size = size;

    return 0;
}

